package org.kernely.persistence;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.SessionFactory;
import org.kernely.persistence.service.SessionService;
import org.kernely.persistence.service.SessionServiceImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;

/**
 * Activator of the persistence bundle.
 */
public class Activator implements BundleListener, BundleActivator {

	// the hibernate configuration file loaded at startup
	private URL hibernateConfigFileUrl;

	// the session factory
	private SessionFactory sessionFactory;

	// the dynamic configuration holder
	private DynamicConfigurationHolder dynamicConfigurationHolder;

	// the bundle instance
	private static Activator instance;

	/**
	 * The default constructor
	 */
	public Activator() {
		instance = this;
	}

	/**
	 * Handles a bundle changes event
	 */
	public final void bundleChanged(BundleEvent pBundleEvent) {
		// Retrieve the event
		Bundle bundle = pBundleEvent.getBundle();
		// Retriveve all entities of te bundle and refresh hibernate's factory
		List<Class<?>> annotatedClasses = dynamicConfigurationHolder
				.getAnnotatedClass(bundle);
		if (!annotatedClasses.isEmpty()) {
			// add all the classes
			if (pBundleEvent.getType() == BundleEvent.STARTED) {
				dynamicConfigurationHolder
						.addAnnotatedClasses(annotatedClasses);
				sessionFactory = dynamicConfigurationHolder.refreshFactory();
			} else if (pBundleEvent.getType() == BundleEvent.STOPPED) {

				dynamicConfigurationHolder
						.removeAnnotatedClasses(annotatedClasses);
				sessionFactory = dynamicConfigurationHolder.refreshFactory();
			}
			
		}

	}

	/**
	 * {@inheritDoc}
	 */
	public final void start(BundleContext pBundleContext) throws Exception {

		// ServiceReference logRef = pBundleContext
		// .getServiceReference(LogService.class.getName());
		// if (logRef != null) {
		// LogService log = (LogService) pBundleContext.getService(logRef);
		// DynamicConfigurationHolder.setLogger(log);
		// SessionServiceImpl.setLogger(log);
		// }

		hibernateConfigFileUrl = pBundleContext.getBundle().getResource(
				"hibernate.cfg.xml");
		// create the Dynamic configuration Holder
		dynamicConfigurationHolder = new DynamicConfigurationHolder();
		dynamicConfigurationHolder.setConfigurationFile(hibernateConfigFileUrl);

		// start listening for bundles
		pBundleContext.addBundleListener(this);

		// look for classes in current bundles
		Bundle[] bundles = pBundleContext.getBundles();
		List<Class<?>> classes = new ArrayList<Class<?>>();
		for (Bundle bundle : bundles) {
			classes.addAll(dynamicConfigurationHolder.getAnnotatedClass(bundle));
		}
		dynamicConfigurationHolder.setAnnotatedClassList(classes);
		sessionFactory = dynamicConfigurationHolder.refreshFactory();

		// register services
		pBundleContext.registerService(SessionService.class.getName(),
				new SessionServiceImpl(), null);		
	}

	/**
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public final void stop(BundleContext pBundleContext) throws Exception {
		pBundleContext.removeBundleListener(this);
	}

	/**
	 * The method return the bundle activator
	 * 
	 * @return the bundle activator
	 */
	public static Activator getInstance() {
		return instance;
	}

	/**
	 * The method set the session factory
	 * 
	 * @return the hibernate session factory
	 */

	public final SessionFactory getSessionFactory() {
		return sessionFactory;
	}

}